/*
 * ksProperty.h
 *
 *  Created on: Aug 5, 2011
 *      Author: wang
 */

#ifndef KSPROPERTY_H_
#define KSPROPERTY_H_
#include "ksDefines.h"
#include <cstddef>
#include "ksException.h"
#include <iostream>

template<typename T>
struct NoChecking
{
    static void check(T& t)
    {

    }
};

template<typename T>
struct EnforcePtrNotNull
{
    static void check(T* p)
    {
        if (!p)
        {
            throw ksException("pointer is null");
        }
    }
};

template<typename _class, template<typename > class checkPolicy = NoChecking>
class ksProperty
{
public:
    void operator =(const _class value)
    {
        _value = value;
    }
    operator _class() const
    {
        return _value;
    }
protected:
    _class _value;
};

template<typename _class, int _capacity, template<typename > class checkPolicy = NoChecking>
class ksBufferProperty
{
public:
    void operator =(const _class* value)
    {
        _class* temp = (_class*) value;
        _class* valueTemp = _value;
        _class* valueEnd = _value + _capacity - 1;
        while (*temp && valueTemp != valueEnd)
        {
            *valueTemp++ = *temp++;
        }
        *valueTemp = 0x00;
        //safe_strcopy(_value, value, _capacity);
    }
    operator _class*() const
    {
        return (_class*) _value;
    }
private:
    _class _value[_capacity];
};

template<typename _class, template<typename > class checkPolicy = EnforcePtrNotNull>
class ksLinkedProperty
{
public:
    ksLinkedProperty()
            : _valuePtr(NULL)
    {

    }
public:
    void linkWith(_class* valuePtr)
    {
        _valuePtr = valuePtr;
    }
public:
    void operator =(const _class value)
    {
        checkPolicy<_class>::check(_valuePtr);
        *_valuePtr = value;
    }
    operator _class() const
    {
        checkPolicy<_class>::check(_valuePtr);
        return *_valuePtr;
    }
private:
    _class* _valuePtr;
};

template<typename _class, int _capacity, template<typename > class checkPolicy = EnforcePtrNotNull>
class ksLinkedBufferProperty
{
public:
    ksLinkedBufferProperty()
            : _valuePtr(NULL)
    {

    }
public:
    void linkWith(_class* valuePtr)
    {
        _valuePtr = valuePtr;
    }
public:
    void operator =(const _class* value)
    {
        checkPolicy<_class>::check(_valuePtr);
        _class* temp = (_class*) value;
        _class* valueTemp = _valuePtr;
        _class* valueEnd = _valuePtr + _capacity - 1;
        while (*temp && valueTemp != valueEnd)
        {
            *valueTemp++ = *temp++;
        }
        *valueTemp = 0x00;
    }
    operator _class*() const
    {
        checkPolicy<_class>::check(_valuePtr);
        return (_class*) _valuePtr;
    }
private:
    _class* _valuePtr;
};

template<int _capacity, template<typename > class checkPolicy /*= EnforcePtrNotNull*/>
class ksLinkedBufferProperty<char, _capacity, checkPolicy>
{
public:
    ksLinkedBufferProperty()
            : _valuePtr(NULL)
    {

    }
public:
    void linkWith(char* valuePtr)
    {
        _valuePtr = valuePtr;
    }
public:
    void operator =(const char* value)
    {
        checkPolicy<char>::check(_valuePtr);
        safe_strcopy(_valuePtr, value, _capacity);
    }
    operator char*() const
    {
        checkPolicy<char>::check(_valuePtr);
        return (char*) _valuePtr;
    }
private:
    char* _valuePtr;
};
#endif /* KSPROPERTY_H_ */
